package com.atguigu.yygh.hosp.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.yygh.cmn.client.DictFeignClient;
import com.atguigu.yygh.common.handler.YyghException;
import com.atguigu.yygh.common.utils.MD5;
import com.atguigu.yygh.enums.DictEnum;
import com.atguigu.yygh.hosp.repository.HospitalRepository;
import com.atguigu.yygh.hosp.service.HospitalService;
import com.atguigu.yygh.hosp.service.HospitalSetService;
import com.atguigu.yygh.model.hosp.Hospital;
import com.atguigu.yygh.vo.hosp.HospitalQueryVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 杨林
 * @create 2022-11-06 18:13 星期日
 * description:
 */
@Service
public class HospitalServiceImpl implements HospitalService {

    @Autowired
    private HospitalRepository hospitalRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private HospitalSetService hospitalSetService;

    //注入远程调用数据字典
    @Autowired
    private DictFeignClient dictFeignClient;


    //添加医院
    @Override
    public void save(Map<String, Object> paramMap) {
        //1.json转对象
        String jsonString = JSONObject.toJSONString(paramMap);
        Hospital hospital = JSONObject.parseObject(jsonString,Hospital.class);

        //2.根据医院编号查询该医院是否已经添加
        String hoscode = hospital.getHoscode();

        //方法1：
        Hospital hosp = hospitalRepository.findByHoscode(hoscode);
        //方法2：
//        Query query = new Query(Criteria.where("hoscode").is(hoscode));
//        List<Hospital> hosp = mongoTemplate.find(query, Hospital.class);

        //对签名校验
        //获取医院端传入的签名信息（此签名信息已经经过MD5加密处理）
        String sign = (String)paramMap.get("sign");
        //获取尚医通数据库中保存的医院签名信息 (该签名信息未进行MD5加密  需要对其进行MD5加密)
        String tempKey = hospitalSetService.getSignKey(hoscode);
        String signKey = MD5.encrypt(tempKey);
        if (!sign.equals(signKey)){
           throw new YyghException(20001, "签名校验失败");
        }

        //2.1对hoscode进行非空校验
        if (StringUtils.isEmpty(hoscode)){
            throw  new YyghException(20001,"医院编号不能为空");
        }

        if (hosp == null){
            //说明该医院未添加过  对该医院进行添加
            hospital.setCreateTime(new Date());
            hospital.setUpdateTime(new Date());
            hospital.setStatus(1);
        }else{
            //说明该医院已经添加过了，则修改该医院
            hospital.setId(hosp.getId()); //根据id进行修改  因此需要传入id
            hospital.setUpdateTime(new Date());
            hospital.setCreateTime(hosp.getCreateTime());
            hospital.setStatus(1);
        }

        hospitalRepository.save(hospital);  //根据id进行修改

    }

    /**
     * 根据医院编号查询
     * @param hoscode
     * @return
     */
    @Override
    public Hospital getByHoscode(String hoscode) {

        return hospitalRepository.findByHoscode(hoscode);
    }

    /**
     * 分页查询医院列表
     */
    @Override
    public Page<Hospital> selectPage(Integer pageNum, Integer limit, HospitalQueryVo hospitalQueryVo) {
        //排序和分页查询
        Sort sort = Sort.by(Sort.Direction.DESC,"createTime");
        Pageable pageable = PageRequest.of(pageNum - 1, limit, sort);

        //查询条件
        Hospital hospital = new Hospital();
        BeanUtils.copyProperties(hospitalQueryVo, hospital);

        //模糊查询
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)  //模糊匹配
                .withIgnoreCase(true); //忽略大小写

        Example example = Example.of(hospital, matcher);
        Page pageResult = hospitalRepository.findAll(example, pageable);

        ////封装医院等级数据（遍历每一个Hospital对象，封装医院等级名称+省市区）
        List<Hospital> content = pageResult.getContent();
        for (Hospital hospital1 : content) {
            this.packHospital(hospital1);
        }

        return pageResult;
    }

    /**
     * 修改医院状态
     */
    @Override
    public void updateStatus(String id, Integer status) {
        //根据医院id获取对应的医院
        Hospital hospital = mongoTemplate.findById(id, Hospital.class);
        if (hospital == null){
            throw new YyghException(20001, "该医院不存在");
        }
        if (status != 0 && status != 1){
            throw new YyghException(20001, "非法的状态");
        }
        hospital.setStatus(status);
        hospital.setCreateTime(new Date());
        //将修改后的医院信息保存
        hospitalRepository.save(hospital);
    }

    /**
     * 显示医院详细信息
     */
    @Override
    public Map<String, Object> show(String id) {
        //根据id查询hospital
        Hospital hospital = hospitalRepository.findById(id).get();

        //封装hospital对象
        hospital = this.packHospital(hospital);

        //封装result返回值
        Map<String,Object> result = new HashMap<>();
        result.put("hospital", hospital);
        result.put("bookingRule", hospital.getBookingRule());

        return result;
    }

    //根据医院名字查询医院（模糊查询）
    @Override
    public List<Hospital> getByHosname(String hosname) {
        if (StringUtils.isEmpty(hosname)){
            throw new YyghException(20001, "医院名字不能为空");
        }
        //findHospitalByHosnameLike 根据医院名字查询医院的方法（支持模糊匹配）
        List<Hospital> hospitalList = hospitalRepository.findHospitalByHosnameLike(hosname);
        return hospitalList;
    }

    /**
     * 根据hoscode获取hospital
     */
    @Override
    public Map<String, Object> item(String hoscode) {
        if (StringUtils.isEmpty(hoscode)){
            throw  new YyghException(20001, "医院编码不能为空");
        }
        Hospital hospital = hospitalRepository.findByHoscode(hoscode);

        Map<String,Object> map = new HashMap<>();
        map.put("hospital", hospital);
        map.put("bookingRule", hospital.getBookingRule());

        return map;
    }

    //封装医院的等级数据的方法
    private Hospital packHospital(Hospital hospital){

        //医院等级名称
        String hostypeString = dictFeignClient.getName(DictEnum.HOSTYPE.getDictCode(), hospital.getHostype());

        //省份名称
        String provinceCode = dictFeignClient.getName(hospital.getProvinceCode());

        //城市名称
        String cityCode = dictFeignClient.getName(hospital.getCityCode());

        //区名称
        String districtCode = dictFeignClient.getName(hospital.getDistrictCode());

        hospital.getParam().put("hostypeString", hostypeString);
        hospital.getParam().put("fullAddress", provinceCode + cityCode + districtCode + hospital.getAddress());
        return hospital;
    }

}
